/*
 * FrontEnd.java
 *
 * Created on June 11, 2002, 12:14 PM
 */

package com.xtera.nuwave.tools.redundancy.emsapp;

import java.text.*;
import java.lang.*;
import java.net.*;
import java.io.*;
import java.util.*;
import javax.net.*;
import com.sun.net.ssl.*;
import javax.net.ssl.*;

/**
 *
 * @author  llaranje
 * @version 
 */
public class FrontEnd {
    
    static final int port = 2200;
    static final String ruleofthumb = "4c6c14a5de1cacbdab5dcf71e0078c7f";
    static PrintWriter ofile = null;
    
    static private boolean checkWithRedMan(BufferedReader in, PrintWriter out) {
        try {              
            if (out != null) {
                String msg = "EMS " + ruleofthumb;
                             
                // System.out.println("opint: user/passwd to RedMan = " + msg); 
                out.println(msg);
                out.flush();
                
            }
            else {
                ofile.println("Not connected to RedMan");
                ofile.flush();
                return(false);
            }
            String resp = in.readLine();
            if ((resp == null) || (resp.length() == 0) || !resp.equals("ACK")) {
                ofile.println("Authentication failed = resp = " + resp); 
                ofile.flush();
                return(false);
            }
            else {
                ofile.println("Authentication suceeded");
                ofile.flush();
                return(true);
            }
        }
        catch (Exception e) {
            ofile.println("Exception: " + e.getMessage());
            ofile.flush();
            return(false);
        }
    }   

    /** Creates new FrontEnd */
    private static void DoSomeWork() {
        String msg;
        DateFormat time = null;
        String localhost = null;
        boolean start = true;
        SSLSocketFactory sslFact = null;
        
        try {
            time = DateFormat.getTimeInstance(DateFormat.FULL);
            System.out.println("EMS FrontEnd running at " + time.format(new Date()));
            localhost = InetAddress.getLocalHost().getHostName();
            System.out.println("EMS FrontEnd running at " + time.format(new Date()));
            System.out.println("Localhost = " + localhost);
        }
        catch (Exception e) {
            System.out.println(e.getMessage());
            System.out.flush();
            System.exit(1);
        }

        try {           
            // Open file to write
            // String filename = "/tmp/FE" + localhost + ".log";
            String filename = "../logs/FE" + localhost + ".log";
            OutputStream ostream = new FileOutputStream(filename, true);
            ofile = new PrintWriter(new OutputStreamWriter(ostream));
            ofile.println("EMS BackEnd running at " + time.format(new Date()));
            ofile.flush();
        }
        catch (Exception e) {
            System.out.println(e.getMessage());
            System.out.flush();
            System.exit(1);
        } 
        
        try {
            time = DateFormat.getTimeInstance(DateFormat.FULL);
            ofile.println("Will initialize provider to obtain socket factory at " + time.format(new Date()));
            ofile.flush();
            System.setProperty("java.protocol.handler.pkgs",
                                             "com.sun.net.ssl.internal.www.protocol");
            java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        
            // Get socket factory
            sslFact = (SSLSocketFactory) SSLSocketFactory.getDefault();
            time = DateFormat.getTimeInstance(DateFormat.FULL);
            ofile.println("Obtained the default SSL socket factory at " + time.format(new Date()));
            ofile.flush();
        }
        catch (Exception e) {
            ofile.println("Exception getting socket factory: " + e.getMessage());
            ofile.flush();
            System.exit(1);
        }
        
        while (true) {           
            try {
                if (!start) {
                    ofile.println("Will sleep 2 secs");
                    Thread.sleep(2000);
                }
                start = false;
                time = DateFormat.getTimeInstance(DateFormat.FULL);
                            
                // Connect to RedMan
                ofile.println("Will connect to RedMan on host " + localhost 
                                                          + ", port = " + String.valueOf(port)
                                                          + " at " + time.format(new Date()));
                //Socket so = new Socket(localhost, port);
                SSLSocket so = (SSLSocket) sslFact.createSocket(localhost, port);
                ofile.println("Connected to RedMan");
                
                so.setTcpNoDelay(true);

                // Get I/O streams to talk to the server
                InputStream sin = so.getInputStream();
                BufferedReader fromRedMan = new BufferedReader(new InputStreamReader(sin));
                OutputStream sout = so.getOutputStream();
                PrintWriter toRedMan = new PrintWriter(new OutputStreamWriter(sout));
                            
                if (!checkWithRedMan(fromRedMan, toRedMan)) {
                    ofile.println("Closing socket");
                    ofile.flush();
                    so.close();
                    continue;
                }
                                                  
                // Send registration message
                toRedMan.println("APP EMS FrontEnd REGISTRATION");
                toRedMan.flush();
                time = DateFormat.getTimeInstance(DateFormat.FULL);
                ofile.println("FrontEnd sent REGISTRATION msg at " + time.format(new Date()));
                ofile.flush();
                msg = fromRedMan.readLine();
                time = DateFormat.getTimeInstance(DateFormat.FULL);
                ofile.println("FrontEnd received msg: \"" + msg + "\" at " + time.format(new Date()));
                ofile.flush();
                toRedMan.println("REQ_INIT_STATE");
                toRedMan.flush();
                time = DateFormat.getTimeInstance(DateFormat.FULL);
                ofile.println("FrontEnd sent REQ_INIT_STATE msg at " + time.format(new Date()));
                ofile.flush();
            
                while ((msg = fromRedMan.readLine()) != null) {
                    time = DateFormat.getTimeInstance(DateFormat.FULL);
                    ofile.println("FrontEnd received msg: \"" + msg + "\" at " + time.format(new Date()));
                    ofile.flush();
                    if (msg.length() == 0) break;
                    //Thread.sleep(2000);
                    if (msg.startsWith("CMD")) {
                        toRedMan.println("ACK");
                        toRedMan.flush();
                    }
                    if (msg.startsWith("TEST PING")) {
                        toRedMan.println("TESTACK");
                        toRedMan.flush();
                    }
                    if (msg.equals("CMD OFFLINE")) System.exit(0);
                }
                time = DateFormat.getTimeInstance(DateFormat.FULL);
                ofile.println("FrontEnd got out of read loop at " + time.format(new Date()));
                ofile.flush();
            }
            catch (Exception e) {
                ofile.println("FrontEnd Exception: " + e.getMessage());
                ofile.flush();               
            }
        }
    }

    /**
    * @param args the command line arguments
    */
    public static void main (String args[]) {
        DoSomeWork();
    }

}
